/*
 * @(#) UIOrder.java 2013-7-24 上午11:25:01
 *
 * Copyright 2013 Rockwell Automation, Inc. All rights reserved.
 * Rockwell Automation PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */package com.osi.mes.pm.object;

import java.math.BigDecimal;
import java.util.Vector;

import com.datasweep.compatibility.client.BillOfMaterials;
import com.datasweep.compatibility.client.BomItem;
import com.datasweep.compatibility.client.Box;
import com.datasweep.compatibility.client.BoxFilter;
import com.datasweep.compatibility.client.DatasweepException;
import com.datasweep.compatibility.client.Lot;
import com.datasweep.compatibility.client.Order;
import com.datasweep.compatibility.client.OrderItem;
import com.datasweep.compatibility.client.Part;
import com.datasweep.compatibility.client.ProductionLine;
import com.datasweep.compatibility.client.Response;
import com.datasweep.compatibility.client.Route;
import com.datasweep.compatibility.client.Step;
import com.datasweep.compatibility.pnuts.Functions;
import com.datasweep.compatibility.ui.Time;
import com.osi.mes.base.object.UIData;
import com.osi.mes.constants.IDateFormatConstants;
import com.osi.mes.constants.IUDADefinitions;
import com.osi.mes.pm.util.OrderTypeUtil;
import com.osi.mes.utils.StringUtils;
import com.rockwell.ftpc.framework.common.DateTimeUtils;

/**
 * 用于界面显示用的工单
 * @author Nemo, 2013-7-24 上午11:57:21
 */
public class UIOrder extends UIData
{
	Functions functions;
	OrderItem orderItem;
	Lot orderLot;
	Vector<Lot> lots = new Vector<Lot>();
	BillOfMaterials billOfMaterials;
	public UIOrder(Order order,Functions functions)
	{
		super(order);
		if(order != null){
			this.functions = functions;
			this.orderItem = (OrderItem) order.getOrderItems().firstElement();
			populateLots();
		}
		if(StringUtils.isNull(order.getUDA(IUDADefinitions.UDA_ORDER_SEQUENCE)))
			setOrderSequence(1);
		if(getPlannedTimeValue() == null)
			setPlannedTime(functions.getDBTime());
	}
	
	private void populateLots()
	{
		this.lots = new Vector<Lot>();
		Vector<Lot> lots = getObject().getLots();
		if(lots != null && lots.size()>0)
		{
			for (int i = 0; i < lots.size(); i++)
			{
				Lot lot = lots.get(i);
				if(lot.getName().equals(getOrderName()))
				{
					orderLot = lot;
					this.billOfMaterials = lot.getBillOfMaterials();
				}
				else
				{
					if(lot.getLotType() == Lot.BULK || lot.getLotType() == Lot.FLOW)
						this.lots.add(lot);
				}
			}
		}
	}

	/**
	 * 获得工单名称
	 */
	public String getOrderName(){
		return getObject().getOrderNumber();
	}
	
	/**
	 * 获得当前产量
	 */
	public int getCurrentBoxQuantity()
	{
		BoxFilter boxFilter = functions.createBoxFilter();
		boxFilter.forUda2EqualTo(getOrderName());
		Vector<Box> boxes = functions.getFilteredBoxes(boxFilter);
		int qty = 0;
		for (int i = 0; i < boxes.size(); i++)
		{
			Box box = boxes.get(i);
			qty += Integer.parseInt(box.getUDA(0));
		}
		return qty;
	}
	
	/**
	 * 刷新
	 */
	public void refresh() throws DatasweepException
	{
		Order order = getObject();
		order.refresh();
		this.orderItem = (OrderItem) order.getOrderItems().firstElement();
		Vector<Lot> lots = order.getLots();
		if(lots != null && lots.size()>0)
		{
			for (int i = 0; i < lots.size(); i++)
			{
				Lot lot = lots.get(i);
				if(lot.getName().equals(getOrderName()))
				{
					orderLot = lot;
					this.billOfMaterials = lot.getBillOfMaterials();
				}
				else
				{
					this.lots.add(lot);
				}
			}
		}
	}
	
	/**
	 * 获得子工单
	 */
	public OrderItem getOrderItem(){
		return this.orderItem;
	}
	
	/**
	 * 获得当前在制品
	 */
	public Lot getLot()
	{
		if(orderLot != null)
			orderLot.refresh();
		return this.orderLot;
	}
	
	/**
	 * 获得所有子批次
	 */
	public Vector<Lot> getLots()
	{
		populateLots();
		return lots;
	}
	
	/**
	 * 获得子批次
	 */
	public Lot getLot(String lotName)
	{
		for (int i = 0; i < lots.size(); i++)
		{
			Lot lot = lots.get(i);
			if(lotName.equals(lot.getName()))
			{
				return lot;
			}
		}
		return null;
	}
	
	/**
	 * 获得实际开始时间
	 */
	public Time getStartedTime()
	{
		return getObject().getUDT(1);
	}
	
	/**
	 * 设置计划时间
	 */
	public void setPlannedTime(Time time)
	{
		orderItem.setPlannedStartTime(time);
	}
	
	/**
	 * 获得工艺路径
	 */
	public String getRoute()
	{
		Route route = getRouteValue();
		return route.getDescription();
	}
	
	/**
	 * 获得工艺路径
	 */
	public Route getRouteValue()
	{
		Route route = null;
		Lot lot = getLot();
		if(lot != null)
		{
			route = lot.getRoute();
			if(route != null)
			{
				return route;
			}
		}
		String routeName = orderItem.getPlannedRoute();
		route = functions.getRoute(routeName);
		return route;
	}
	
	/**
	 * 获得工单状态
	 */
	public String getOrderState()
	{
		return getObject().getOrderState();
	}
	
	/**
	 * 获得计划时间
	 */
	public String getPlannedTime()
	{
		Time plannedTime = orderItem.getPlannedStartTime();
		return DateTimeUtils.formatDate(plannedTime, IDateFormatConstants.DATE_TIME_FORMAT_DAY);
	}
	
	/**
	 * 获得计划时间
	 */
	public Time getPlannedTimeValue()
	{
		return orderItem.getPlannedStartTime();
	}
	
	/**
	 * 设置产品
	 */
	public void setPart(Part part)
	{
		orderItem.setPartNumber(part.getPartNumber());
		orderItem.setPartRevision(part.getPartRevision());
		orderItem.setPart(part);
	}
	
	/**
	 * 获得产品
	 */
	public Part getPart()
	{
		return orderItem.getPart();
	}
	
	/**
	 * 获得产品代码
	 */
	public String getPartDescription()
	{
		Part part = orderItem.getPart();
		return part.getDescription();
	}
	
	public String getPartNumber()
	{
		Part part = orderItem.getPart();
		return part.getPartNumber();
	}
	
	/**
	 * 设置产线
	 */
	public void setProductionLine(String productionLineName)
	{
		orderItem.setPlannedProductionLine(productionLineName);
	}
	
	/**
	 * 获得产线
	 */
	public String getProductionLine()
	{
		String productionLineName = orderItem.getPlannedProductionLine();
		ProductionLine productionLine = functions.getProductionLineByName(productionLineName);
		return productionLine.getDescription();
	}
	
	/**
	 * 确认物料
	 */
	public Response applyRuntimeBom() throws Exception{
		if(billOfMaterials.isChanged())
		{
//			return billOfMaterials.save();
			BillOfMaterials buildtimeBom = functions.createBOM();
			buildtimeBom.setBomName(billOfMaterials.getBomName());
			buildtimeBom.setBomRevision(billOfMaterials.getBomRevision());
			
			BigDecimal preQuantity = getPlannedQuantityValue();
			
			Vector bomItems = billOfMaterials.getBomItems();
			for (int i = 0; i < bomItems.size(); i++)
			{
				BomItem bomItem = (BomItem) bomItems.get(i);
				BomItem newBomItem = functions.createBomItem();
				newBomItem.setPartNumber(bomItem.getPartNumber());
				newBomItem.setPartRevision(bomItem.getPartRevision());
				newBomItem.setDescription(bomItem.getDescription());
				newBomItem.setBomItemName(bomItem.getBomItemName());
				newBomItem.setQuantity(bomItem.getPreciseQuantity().divide(preQuantity,3));
				newBomItem.setDecimalScale(bomItem.getDecimalScale());
				newBomItem.setCategory(bomItem.getCategory());
				newBomItem.setUDA(
					bomItem.getUDA(1), 1);
				newBomItem.setUDA(
					bomItem.getUDA(IUDADefinitions.UDA_BOM_ITEM_CONFIRM_TIME), IUDADefinitions.UDA_BOM_ITEM_CONFIRM_TIME);
				buildtimeBom.addBomItem(newBomItem);
			}
			 Response response = getLot().applyRuntimeBom(buildtimeBom);
			 if (response.isError())
			{
				throw new Exception("物料确认失败");
			}
			 
		}
		getObject().setAddress1(
			"OK");
		getObject().save();
		refresh();
		return new Response();
	}
	
	/**
	 * 获得产线
	 */
	public String getProductionLineValue()
	{
		return orderItem.getPlannedProductionLine();
	}
	
	/**
	 * 设置工艺路径
	 */
	public void setRoute(String routeName)
	{
		orderItem.setPlannedRoute(routeName);
	}
	
	/**
	 * 设置工艺路径
	 */
	public void setRoute(Route route)
	{
		orderItem.setPlannedRoute(route.getRouteName());
	}
	
	/**
	 * 设置计划数量
	 */
	public void setPlannedQuantity(Float quantity)
	{
		setPlannedQuantity(new BigDecimal(quantity));
	}
	
	/**
	 * 设置计划数量
	 */
	public void setPlannedQuantity(BigDecimal quantity)
	{
		orderItem.setQuantityOrdered(quantity);
	}
	
	/**
	 * 获得计划时间
	 */
	public String getFinishedTime()
	{
		Time finished = orderItem.getFinishedTime();
		return DateTimeUtils.formatDate(finished, IDateFormatConstants.DATE_TIME_FORMAT_DAY);
	}
	
	/**
	 * 添加一个消耗物料
	 * @param partNumber	物料代码
	 * @param quantity		数量
	 */
	public BomItem addBomItem(Part part,float quantity) throws Exception
	{
		if(billOfMaterials == null)
		{
			billOfMaterials = functions.createBOM();
			billOfMaterials.setName(orderItem.getPartNumber());
			billOfMaterials.setBomRevision("1");
		}
		BomItem bomItem = billOfMaterials.addBomItem(part);
		bomItem.setQuantity(new BigDecimal(quantity));
		bomItem.setDecimalScale(2);
		return bomItem;
	}
	
	/**
	 * 删除一个物料
	 */
	public void removeBomItem(BomItem bomItem)
	{
		this.billOfMaterials.removeBomItem(bomItem);
	}
	
	/**
	 * 获得计划数量
	 */
	public String getPlannedQuantity()
	{
		return orderItem.getPreciseQuantityOrdered().setScale(2, 3).toString();
	}
	
	/**
	 * 获得计划数量
	 */
	public BigDecimal getPlannedQuantityValue()
	{
		return orderItem.getPreciseQuantityOrdered();
	}
	
	/**
	 * 设置BOM
	 */
	public void setBom(BillOfMaterials billOfMaterials)
	{
		if(getLot() == null)
		{
			if(functions.getBom(billOfMaterials.getBomName(), billOfMaterials.getBomRevision())!= null)
			{
				orderItem.setBomName(billOfMaterials.getBomName());
				orderItem.setBomRevision(billOfMaterials.getBomRevision());
			}
		}
		this.billOfMaterials = billOfMaterials;
	}
	
	/**
	 * 获得BOM
	 */
	public BillOfMaterials getBom()
	{
		return this.billOfMaterials;
	}
	 
	/**
	 * 设置起始工序
	 */
	public void setStartStep(Step step)
	{
		getObject().setUDA(step.getName(), IUDADefinitions.UDA_ORDER_START_STEP);
	}
	
	/**
	 * 获得起始工序
	 */
	public String getStartStep()
	{
		Step step = getStartStepValue();
		return step.getOperation().getDescription();
	}
	
	/**
	 * 获得起始工序
	 */
	public Step getStartStepValue()
	{
		String stepName = getObject().getUDA(3);
		String routeName = orderItem.getPlannedRoute();
		Route route = functions.getRoute(routeName);
		Step step = route.getStep(stepName);
		return step;
	}
	
	/**
	 * 设置工单类型
	 */
	public void setOrderType(String orderType)
	{
		orderType = OrderTypeUtil.getOrderTypeKey(orderType);
		getObject().setUDA(orderType,IUDADefinitions.UDA_ORDER_TYPE);
		setMaterialSplitMethod(null);
	}
	
	/**
	 * 获得工单类型
	 */
	public String getOrderType()
	{
		String orderType = getObject().getUDA(IUDADefinitions.UDA_ORDER_TYPE);
		return OrderTypeUtil.getOrderTypeName(orderType);
	}
	
	/**
	 * 设置生产序号
	 */
	public void setOrderSequence(Integer sequence)
	{
		getObject().setUDA(String.valueOf(sequence), IUDADefinitions.UDA_ORDER_SEQUENCE);
	}
	
	/**
	 * 获得生产序号
	 */
	public Integer getOrderSequence()
	{
		String sequence = getObject().getUDA(IUDADefinitions.UDA_ORDER_SEQUENCE);
		return Integer.valueOf(sequence);
	}
	
	public void setMaterialSplitMethod(String materialSplitMethod)
	{
		orderItem.setUDA(materialSplitMethod,IUDADefinitions.UDA_ORDER_ITEM_MAT_SPLIT_METHOD);
	}
	
	/**
	 * 获得原料分切方法
	 */
	public String getMaterialSplitMethod()
	{
		return orderItem.getUDA(IUDADefinitions.UDA_ORDER_ITEM_MAT_SPLIT_METHOD);
	}
	
	/**
	 * 删除工单
	 */
	public Response remove()
	{
		return getObject().remove(null, null);
	}
	
	/**
	 * 获得发布时间
	 */
	public String getPublishDate()
	{
		Time publishDate = getObject().getUDT(IUDADefinitions.UDT_ORDER_PUBLISH_DATE);
		if(publishDate != null)
			return DateTimeUtils.formatDate(publishDate, IDateFormatConstants.DATE_TIME_FORMAT_DAY);
		return null;
	}
	
	/**
	 * 判断是否为新建
	 */
	public Boolean isNew()
	{
		return getObject().isNew();
	}
	
	@Override
	public Order getObject()
	{
		return (Order) super.getObject();
	}
	
	@Override
	public String toString()
	{
		return getObject().getOrderNumber()+" "+getPartDescription();
	}
	
	/**
	 * 设置出口号
	 * @param shipNum
	 */
	public void setShipNum(String shipNum)
	{
		getObject().setAddress2(shipNum);
	}
	
	/**
	 * 获得出口号
	 */
	public String getShipNum()
	{
		return getObject().getAddress2();
	}
	
	/**
	 * 设置班别
	 * @param shift
	 */
	public void setShift(String shift)
	{
		getObject().setContactPerson(shift);
	}
	
	/**
	 * 获得班别
	 */
	public String getShift()
	{
		return getObject().getContactPerson();
	}
	
	/**
	 * 设置备注
	 * @param comment
	 */
	public void setComment(String comment)
	{
		getObject().setComment(comment);
	}
	
	/**
	 * 获得备注
	 * @return
	 */
	public String getComment()
	{
		return getObject().getComment();
	}

	/**
	 * 更改计划数量
	 * @param bigDecimal	计划数量
	 */
	public void changePlannedQty(BigDecimal bigDecimal) throws DatasweepException
	{
		setPlannedQuantity(bigDecimal);
		getObject().save();
		refresh();
	}
}
